package com.service;

import java.io.UnsupportedEncodingException;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

public class ServerHandler extends ChannelInboundHandlerAdapter {
	ServerListener listener;
	ByteBuf bodyBuf = null;
	byte[] leftBytes = null;
	SocketMessage tempMsg = null;
	private int readSize = 0;
	public ServerHandler(ServerListener listener){
		this.listener = listener;
	}
	
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		listener.onConnected(ctx);
		super.channelActive(ctx);
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg)
			throws Exception {
		ByteBuf buf = (ByteBuf)msg;
		byte[] req = new byte[buf.readableBytes()];
		buf.readBytes(req);
		if(leftBytes == null){
			leftBytes = req;
		}
		while(tempMsg != null || (leftBytes != null && leftBytes.length >= SocketMessage.HEADER_LENGTH)){
			if(tempMsg == null){
				tempMsg = new SocketMessage(leftBytes);
				leftBytes = BitConverter.subBytes(leftBytes, SocketMessage.HEADER_LENGTH, leftBytes.length - SocketMessage.HEADER_LENGTH);
			}
			int max = 0;
			if(tempMsg.getBodyLength() > 0){
				if(bodyBuf == null){
					bodyBuf = Unpooled.buffer(tempMsg.getBodyLength());
				}
				max = Math.min(tempMsg.getBodyLength() - readSize, leftBytes.length);
				bodyBuf.writeBytes(leftBytes, 0, max);
				readSize += max;
			}
			if(readSize >= tempMsg.getBodyLength()){ //已完整获取到数据包
				if(tempMsg.getBodyLength() > 0 && tempMsg.getBodyData() == null){
					tempMsg.setBodyData(bodyBuf.array());
					bodyBuf.clear();
					bodyBuf.alloc();
					bodyBuf = null;
					if(tempMsg.getBodyData()[0] == 123 || tempMsg.getBodyData()[0] == 91){
		        		try {
		        			tempMsg.setBodyJson(new String(tempMsg.getBodyData(), "utf-8"));
						} catch (UnsupportedEncodingException e) {
							e.printStackTrace();
						}
		        	}
				}
				listener.onReceived(tempMsg, ctx);//触发接收事件
				readSize = 0;
				leftBytes = BitConverter.subBytes(leftBytes, max, leftBytes.length - max);
				if(leftBytes.length == 0){
					leftBytes = null;
				}
				tempMsg = null;
			}else{
				leftBytes = null;
				break;
			}
		}
		super.channelRead(ctx, msg);
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
			throws Exception {
		listener.onError(ctx, cause);
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		listener.onDisConnected(ctx);
		super.channelInactive(ctx);
	}

	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
			throws Exception {
		super.userEventTriggered(ctx, evt);
		if (evt instanceof IdleStateEvent) {
			IdleStateEvent event = (IdleStateEvent) evt;
			if (event.state().equals(IdleState.READER_IDLE)) {
			} else if (event.state().equals(IdleState.WRITER_IDLE)) {
				listener.onTimeout(ctx);
			} else if (event.state().equals(IdleState.ALL_IDLE)) {
			}
		}
	}
}
